﻿using Shop.Model.DB;
using Shop.Model.SpecGroupT;
using Shop.RemoteModel.SpecGroupTemplate.Model;
using Shop.Repository;
using SqlSugar;
using WeDonekRpc.Client;
using WeDonekRpc.Helper;

namespace Shop.Collect.lmpl
{
    internal class SpecGroupTemplateCollect : ISpecGroupTemplateCollect
    {
        private readonly ISpecGroupTemplateRepository _Repository;

        public SpecGroupTemplateCollect (ISpecGroupTemplateRepository repository)
        {
            this._Repository = repository;
        }
        public Result Get<Result> (long id) where Result : class
        {
            return this._Repository.Get<Result>(id);
        }
        public DBSpecGroupTemplate Get (long id)
        {
            return this._Repository.Get(id);
        }
        public bool Set (DBSpecGroupTemplate source, SpecGroupTSet set)
        {
            if (source.IsEnable)
            {
                throw new ErrorException("shop.spec.group.already.enable");
            }
            else if (( source.GroupName != set.GroupName || set.CategoryId != source.CategoryId ) && this._Repository.IsExist(c => c.CategoryId == set.CategoryId && c.GroupName == set.GroupName))
            {
                throw new ErrorException("shop.spec.group.name.repeat");
            }
            SpecGroupTSetArg arg = set.ConvertMap<SpecGroupTSet, SpecGroupTSetArg>();
            arg.Sort = source.Sort;
            if (source.CategoryId != set.CategoryId)
            {
                arg.Sort = this._Repository.Max(c => c.CategoryId == set.CategoryId, c => c.Sort) + 1;
            }
            else
            {
                arg.Sort = source.Sort;
            }
            return this._Repository.Update(source, set);
        }
        public long Add (SpecGroupTSet add)
        {
            if (this._Repository.IsExist(c => c.CategoryId == add.CategoryId && c.GroupName == add.GroupName))
            {
                throw new ErrorException("shop.spec.group.name.repeat");
            }
            DBSpecGroupTemplate data = add.ConvertMap<SpecGroupTSet, DBSpecGroupTemplate>();
            data.Sort = this._Repository.Max(c => c.CategoryId == add.CategoryId, c => c.Sort) + 1;
            return this._Repository.Add(data);
        }
        public Result[] GetEnables<Result> (long categoryId) where Result : class, new()
        {
            return this._Repository.Gets<Result>(a => a.CategoryId == categoryId && a.IsEnable, "Sort");
        }
        public Result[] Gets<Result> (long categoryId) where Result : class, new()
        {
            return this._Repository.Gets<Result>(a => a.CategoryId == categoryId, "Sort");
        }
        public void SetIsEnable (DBSpecGroupTemplate source, bool isEnable)
        {
            if (source.IsEnable == isEnable)
            {
                return;
            }
            this._Repository.SetIsEnable(source.Id, isEnable);
        }
        public Dictionary<long, int> SetSort (DBSpecGroupTemplate template, int sort)
        {
            int num = template.Sort - sort;
            Dictionary<long, int> sorts = new Dictionary<long, int>()
            {
               {template.Id,sort }
            };
            if (Math.Abs(num) == 1)
            {
                long id = this._Repository.Get(a => a.CategoryId == template.CategoryId && a.Sort == sort, a => a.Id);
                if (id != 0)
                {
                    sorts.Add(id, template.Sort);
                }
            }
            else
            {
                int begin = template.Sort;
                int end = sort;
                if (begin > end)
                {
                    begin = sort;
                    end = template.Sort - 1;
                }
                else
                {
                    begin += 1;
                }
                var datas = this._Repository.Gets(a => a.CategoryId == template.CategoryId && SqlFunc.Between(a.Sort, begin, end), a => new
                {
                    a.Id,
                    a.Sort
                }).OrderBy(a => a.Sort).ToArray();
                if (!datas.IsNull() && datas[0].Sort == sort)
                {
                    num = num > 0 ? 1 : -1;
                    for (int i = 0; i < datas.Length; i++)
                    {
                        int next = i + 1;
                        var t = datas[i];
                        int s = t.Sort + num;
                        sorts.Add(t.Id, s);
                        if (next != datas.Length && datas[next].Sort != s)
                        {
                            break;
                        }
                    }
                }
            }
            this._Repository.SetSort(sorts);
            return sorts;
        }
        public void Delete (DBSpecGroupTemplate source)
        {
            if (source.IsEnable)
            {
                throw new ErrorException("shop.spec.group.already.enable");
            }
            this._Repository.Delete(source.Id);
        }
    }
}
